Flutter自定义Widget

您所在的位置:网站首页 flutter 输入框高度 Flutter自定义Widget

Flutter自定义Widget

2023-09-28 10:04| 来源: 网络整理| 查看: 265

现在我们有个需求,要求输入完成后所有字母都转大写,看起来很容易,直接写个TextField,然后在onEditingComplete里处理不就行了,但是,你会发现,键盘里还有个下拉按钮,就上面那个按钮,点击它虽然键盘消失了,但根本不执行onEditingComplete,只有点击下面那个按钮才会执行,这样测试肯定不通过,那就在onChange方法里处理?也不行,因为我输入完成后还得访问后台接口,所以不能在onChange方法里处理。

背景讲完了,上代码:

1,使用扩展类extension...on...,扩展下TextField,混入class WidgetsBindingObserver来监听界面的变化,具体监听尺寸变化的方法是didChangeMetrics()

extension TextFieldExtension on TextField{ Widget getKeyboardListenerTextField(){ if(focusNode == null) return this; return KeyboardListenerTextField(child: this); } } class KeyboardListenerTextField extends StatefulWidget { TextField child; KeyboardListenerTextField({ this.child, }); @override _KeyboardListenerTextFieldState createState() => _KeyboardListenerTextFieldState(); } class _KeyboardListenerTextFieldState extends State with WidgetsBindingObserver { //标记键盘是否现实中,默认不显示 bool isKeyboardActived = false; @override void initState() { super.initState(); WidgetsBinding.instance.addObserver(this); } @override void dispose() { super.dispose(); WidgetsBinding.instance.removeObserver(this); widget.child.focusNode.unfocus(); } @override void didChangeMetrics() { super.didChangeMetrics(); WidgetsBinding.instance.addPostFrameCallback((_) { // 当前是安卓系统并且在焦点聚焦的情况下 if (Platform.isAndroid && widget.child.focusNode.hasFocus) { if (isKeyboardActived) { isKeyboardActived = false; // 使输入框失去焦点 widget.child.focusNode.unfocus(); return; } isKeyboardActived = true; } else { isKeyboardActived = false; } }); } @override Widget build(BuildContext context) { return widget.child; } }

2,在使用时直接 

TextField( focusNode: focusNode, onEditingComplete: () { focusNode?.unfocus(); }, onSubmitted: (text) { focusNode?.unfocus(); }, ).getKeyboardListenerTextField();

3,当然,需要监听焦点

focusNode.addListener(() { if (!focusNode.hasFocus) { //失去焦点,说明输入完成,该转大写的转大写,该数据请求的数据请求 } });

最后:这样写也有缺点,因为如果一个界面TextField很多,如果焦点直接从这个TextField到另一个TextField,那第二个 TextField当键盘隐藏时因为键盘状态未变化,所以不会失去焦点,所以这只适合界面有一个TextField的情况。

最后的最后:如果界面就是很多TextField,那可以给整个界面混入WidgetsBindingObserver,监听整个界面的尺寸,设置监听时酱紫写:

double oldBottom = 0; @override void didChangeMetrics() { super.didChangeMetrics(); WidgetsBinding.instance.addPostFrameCallback((_) { var currentBottom = MediaQuery.of(context).viewInsets.bottom; // 如果currentBottom为0,表示键盘消失了,这时候整个界面获取焦点,那TextField自然就失去焦点了 // 为什么还要判断oldBottom,因为在界面没变化的时候,个别机型也会调用这个方法。。。 // 所以必须在oldBottom不为0的时候,才获取焦点,这里坑的我好惨。。。 if(oldBottom != 0 && currentBottom==0){ FocusScope.of(context).requestFocus(FocusNode()); } oldBottom = currentBottom; }); }


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3